package me.yuzho.study.concurrency.waxomatic;

import static net.mindview.util.Print.*;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


class Car {
    private boolean waxOn = false;
    
    
    /** 给车打蜡
     * 
     */
    public synchronized void waxed() {
        waxOn = true; // ready to buffer
        notifyAll();
    }
    
    public synchronized void buffered() {
        waxOn = false; // ready for another coat of wax
        notifyAll();
    }
    
    public synchronized void waitForWaxing() throws InterruptedException {
        while (!waxOn) {
            wait(); // where the task has acquired to lock, when you call wait(), the thread is suspended and the lock if released 
        }
    }
    
    public synchronized void waitForBuffing() throws InterruptedException {
        while (waxOn) {
            wait();
        }
    }
}

class WaxOn implements Runnable {
    private Car car;
    public WaxOn(Car c) { car = c; }
    @Override
    public void run() {
        try {
            
            while(!Thread.interrupted()) {
                printnb("Wax On!");
                TimeUnit.MILLISECONDS.sleep(200);
                car.waxed();
                car.waitForBuffing();
            }
            
        } catch (InterruptedException e) {
            print("Exiting via interrupt");
        }
        
        print("Ending Wax On task");
    }
}

class WaxOff implements Runnable {
    private Car car;
    public WaxOff(Car c) { car = c; }
    @Override
    public void run() {
        try {
            
            while(!Thread.interrupted()) {
                car.waitForWaxing();
                printnb("Wax Off!");
                TimeUnit.MILLISECONDS.sleep(200);
                car.buffered();
                //car.waxed();
                //car.waitForBuffing();
            }
            
        } catch (InterruptedException e) {
            print("Exiting via interrupt");
        }
        
        print("Ending Wax Off task");
    }
}

/** 线程协作的基本示例
 * @author yzhou-citrix
 *
 */
public class WaxOMatic {

    public static void main(String[] args) throws InterruptedException {
        Car car = new Car();
        
        ExecutorService exec = Executors.newCachedThreadPool();
        
        exec.execute(new WaxOff(car));
        exec.execute(new WaxOn(car));
        
        TimeUnit.SECONDS.sleep(5);
        
        exec.shutdownNow();
    }
}
